package org.jeecg.modules.cosmetic.config;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.exception.JeecgBoot401Exception;
import org.jeecg.modules.cosmetic.entity.TUser;
import org.jeecg.modules.cosmetic.service.ITUserService;
import org.jeecg.modules.cosmetic.utils.AuthInfo;
import org.jeecg.modules.cosmetic.utils.CurrentUserUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static org.jeecg.modules.cosmetic.constant.RedisConstants.PRODUCT_USER_TOKEN;

@Component
@Slf4j
public class ApiInterceptor implements HandlerInterceptor {

    @Resource
    private ITUserService itUserService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    private static final String TOKEN = "X-Access-Token";

    private static final Long VALID_TIME = 24 * 60 * 60L;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader(TOKEN);
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter(TOKEN);
        }
        if (StringUtils.isEmpty(token)) {
            Cookie[] cookies = request.getCookies();
            if (cookies == null) {
                throw new JeecgBoot401Exception("请求token为空");
            }
            for (Cookie cookie : cookies) {
                if (Objects.equals(cookie.getName(), TOKEN)) {
                    token = cookie.getValue();
                }
            }
        }
        if (StringUtils.isBlank(token)) {
            throw new JeecgBoot401Exception("请求token为空");
        }
        String tokenKey = String.format(PRODUCT_USER_TOKEN, token);
        String userInfo = stringRedisTemplate.opsForValue().get(tokenKey);
        if (StringUtils.isNotEmpty(userInfo)) {
            AuthInfo authInfo = JSON.parseObject(userInfo, new TypeReference<AuthInfo>() {
            });
            CurrentUserUtil.set(authInfo);
            return true;
        }
        LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<TUser>()
                .eq(TUser::getToken, token);
        TUser tUser = itUserService.getOne(queryWrapper);
        if (ObjectUtil.isEmpty(tUser) || tUser.getStatus() != 0) {
            log.error("用户非法");
            throw new JeecgBoot401Exception("token已失效");
        }
        Long restTime = System.currentTimeMillis() / 1000 - tUser.getTokenValidTime().longValue();
        if (restTime >= VALID_TIME) {
            throw new JeecgBoot401Exception("token已失效");
        }
        AuthInfo authInfo = new AuthInfo();
        authInfo.setId(tUser.getId());
        authInfo.setUserName(tUser.getUserName());
        authInfo.setName(tUser.getName());
        stringRedisTemplate.opsForValue().set(tokenKey, JSON.toJSONString(authInfo), VALID_TIME - restTime, TimeUnit.SECONDS);
        CurrentUserUtil.set(authInfo);
        return true;
    }

}
